package order;


import activity.give.GiveActivitySpecProduct;
import address.Address;
import build.OrderBuilder;
import coupon.DiscountCoupon;
import coupon.WebUserCoupon;
import coupon.WebUserCouponHistory;
import enums.*;
import helper.CacheHelper;
import models.constants.DeletedStatus;
import models.merchant.Merchant;
import models.weixin.WebUser;
import models.weixin.amount.WebUserAccount;
import models.weixin.amount.WebUserAccountHistory;
import play.Logger;
import play.db.jpa.Model;
import product.enums.ProductAttribute;
import product.merchant.ProductSpecMerchant;
import shopcart.ShopCart;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by upshan on 15/7/7.
 */
@Entity
@Table(name = "orders")
public class Order extends Model {


    /**
     * 下单用户
     */
    @JoinColumn(name = "web_user_id", nullable = true)
    @ManyToOne
    public WebUser webUser;

    /**
     * 所属业务员
     */
    @JoinColumn(name = "sale_man_user_id", nullable = true)
    @ManyToOne
    public WebUser saleManUser;

    /**
     * 所属商户
     */
    @JoinColumn(name = "fee_merchant_id", nullable = true)
    @ManyToOne
    public Merchant merchant;


    /**
     * 配送地址
     */
    @JoinColumn(name = "address_id", nullable = true)
    @ManyToOne
    public Address address;


    /**
     * 订单名称
     */
    @Column(name = "name")
    public String name;

    /**
     * 防止后退刷新一直添加订单
     */
    @Column(name = "uuid")
    public String uuid;


    /**
     * 订单号
     */
    @Column(name = "order_no")
    public String orderNumber;


    /**
     * 订单总金额
     */
    @Column(name = "amount")
    public Double amount= 0D;

    /**
     * 订单折扣金额  比如活动折扣 使用优惠券金额  赠送金额
     */
    @Column(name = "discount_pay")
    public Double discountPay= 0D;

    /**
     * 已支付金额 实际支付金额
     */
    @Column(name = "paymented_amount")
    public Double paymentedAmount= 0D;


    /**
     * 合伙人金额
     */
    @Column(name = "partner_amount")
    public Double partnerAmount= 0D;


    /**
     * 支付的运费
     */
    @Column(name = "freight")
    public Double freight = 0D;

    /**
     * 已退款金额
     */
    @Column(name = "refunded_amount")
    public Double refundedAmount= 0D;

    /*
    * 订单支付状态
    */
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    public OrderStatus status;

    /**
     * 订单类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "order_type")
    public OrderType type;


    /**
     * 支付类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "payment_type")
    public PaymentType paymentType;



    /**
     * 订单备注信息
     */
    @Column(name = "remark")
    public String remark;


    /**
     * 付款时间
     */
    @Column(name = "payed_at")
    public Date payedAt;

    /**
     * 创建时间
     */
    @Column(name = "created_at")
    public Date createdAt;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;

//    @OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
//    @OrderBy("id")
    @Transient
    public List<Map<String, Object>> orderItemsMap;

    @Transient
    public String sts;

    @Transient
    public List<OrderItem> orderItems;



    public static Order findByOrderNumber(String orderNumber) {
        return find("orderNumber = ? and deleted = ?", orderNumber , DeletedStatus.UN_DELETED).first();
    }

    /**
     * 根据订单状态查询订单. 将来肯定需要 增加分页功能
     * @param status
     * @return
     */
    public static List<Order> findByStatus(OrderStatus status,WebUser webUser) {
        if(status == null || "".equals(status) || "all".equals(status)){
            return find(" deleted = ? and webUser = ? order by createdAt desc",DeletedStatus.UN_DELETED,webUser).fetch();
        }else {
            return find("deleted = ? and status = ?  and webUser = ? order by createdAt desc" , DeletedStatus.UN_DELETED , status,webUser).fetch();
        }
    }

    /**
     * 根据订单状态查询订单. 将来肯定需要 增加分页功能
     * @param status
     * @return
     */
    public static List<Order> findByStatusAndWebuserAndMerchant(OrderStatus status,WebUser webUser , Merchant merchant) {
        if(status == null || "".equals(status) || "all".equals(status)){
            return find(" deleted = ? and webUser = ? and merchant = ? order by createdAt desc",DeletedStatus.UN_DELETED,webUser , merchant).fetch();
        }else {
            return find("deleted = ? and status = ?  and webUser = ? and merchant = ? order by createdAt desc" , DeletedStatus.UN_DELETED , status,webUser , merchant).fetch();
        }
    }

    /**
     * 根据订单状态查询订单. 将来肯定需要 增加分页功能
     * @param status
     * @return
     */
    public static Long countByStatus(OrderStatus status,WebUser webUser) {
        if(status == null || "".equals(status) ){
            return count(" deleted = ? and webUser = ?",DeletedStatus.UN_DELETED,webUser);
        }else {
            return count("deleted = ? and status = ?  and webUser = ? " , DeletedStatus.UN_DELETED , status,webUser);
        }
    }

    /**
     * 根据订单状态查询订单. 将来肯定需要 增加分页功能
     * @return
     */
    public static Long countByWebUser(WebUser webUser) {
            return count(" deleted = ? and webUser = ? and payedAt != null",DeletedStatus.UN_DELETED,webUser);
    }

    /**
     * 根据订单状态查询订单. 将来肯定需要 增加分页功能
     * @param status
     * @return
     */
    public static Long countByStatusAndWebuserAndMerchant(OrderStatus status,WebUser webUser , Merchant merchant) {
        if(status == null || "".equals(status) ){
            return count(" deleted = ? and webUser = ? and merchant = ?",DeletedStatus.UN_DELETED,webUser , merchant);
        }else {
            return count("deleted = ? and status = ?  and webUser = ? and merchant = ?" , DeletedStatus.UN_DELETED , status,webUser , merchant);
        }
    }


    public static List<OrderItem> getOrderItems(Order order) {
        return OrderItem.findByOrder(order);
    }

    public static List<Order> findByStatusAndDate(OrderStatus status , Date beginAt , Date endAt) {
        return Order.find("deleted = ? and status = ? and createdAt between ? and ?" , DeletedStatus.UN_DELETED , OrderStatus.UNPAID , beginAt , endAt).fetch();
    }

    public static void updateOrderPayStatus(Order order){

            // 修改订单状态
            order.remark = "订单支付异常  人工修改支付状态";
            order.save();
            OrderBuilder.orderNumber(order.orderNumber).changeToPaid();

            // 设置订单支付方式
            setPaymentType(PaymentType.WEIXIN_PUB , order);

            //Redis 更新数量  并且设置购物车
//            updateRedisProduct(order);

            // 如果是充值卡  则 金额充值到账户中
            checkToAccount(order);

            // 如果有代金券赠送政策  则赠送代金券
            DiscountCoupon.checkToCoupon(order);

            //用户消费成功 减少代金券
            checkReduceCoupon(order);

            //修改库存
            changeProductNumber(order);

            //检查是否有赠品
            checkGiveSpecProduct(order);

            Logger.info("订单号为: %s 的订单 支付状态修改成功" , order.orderNumber);


    }


    /**
     * 设置订单支付方式
     * @param payType
     * @param order
     */
    private static void setPaymentType(PaymentType payType , Order order) {
        if(payType != null) {
            order.paymentType = payType;
            order.save();
        }
    }

    /**
     *
     * @param order
     */
    private static void updateRedisProduct(Order order) {
        List<OrderItem> orderItems = OrderItem.getListByOrder(order);
        List<ShopCart> shopCartList = ShopCart.findShopCartByUserAndMerchant(order.webUser, order.merchant.id);
        for(OrderItem oi : orderItems) {
            ProductSpecMerchant psm = OrderItem.getProductSpecMerchantByOrderItem(oi);
            for(ShopCart shopCart : shopCartList) {
                //修改购物车信息
                if(oi.goods == shopCart.goods) {
                    shopCart.status = ShopCartStatus.BUY;
                    shopCart.deleted = DeletedStatus.DELETED;
                    shopCart.save();
                }
            }
            ProductSpecMerchant.subtractRedis(psm , oi.buyNumber);
        }

        //更新购物车缓存数量
        Long shopcartCount = ShopCart.findShopCartSize(order.webUser,order.merchant.id);
        CacheHelper.objectToCache(ShopCart.CACHE_SHOP_CART_COUNT + order.webUser.id + "_" + order.merchant.id , shopcartCount.toString());
    }

    /**
     * 检测产品是否为  充值卡 。 如果为充值卡。 钱充值到 个人帐户中
     * @param order
     */
    private static void checkToAccount(Order order) {
        //查看个人微信账户
        WebUserAccount account = WebUserAccount.findByWebUser(order.webUser);
        // 如果微信账户为空 创建一个微信账户
        if(account == null) {
            account = new WebUserAccount(order.webUser , 0d).save();
        }
        // 查询订单商品类目
        List<OrderItem> orderItems = OrderItem.findByOrder(order);
        for(OrderItem orderItem : orderItems) {
            // 订单商品对应到 商户商品
            ProductSpecMerchant specMerchant = ProductSpecMerchant.findById(orderItem.goods.serialId);
            if(specMerchant != null && specMerchant.productSpec.product != null) {
                if(specMerchant.productSpec.product.type != null && specMerchant.productSpec.product.type == ProductAttribute.RECHARGEABLE_CARD) {
                    // 修改个人中心账户金额
                    account.amount +=  (specMerchant.productSpec.amount + specMerchant.productSpec.giveAmount);
                    account.save();
                    new WebUserAccountHistory(account , specMerchant.productSpec.amount , specMerchant.productSpec.giveAmount , "用户购买:" +specMerchant.productSpec.product.name + "。型号为:" + specMerchant.productSpec.unit).save();
                }
            }
        }
    }

    /**
     * 用户消费成功  减少代金券
     * @param order
     */
    private static void checkReduceCoupon(Order order) {
        WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(order.webUser);
        if(webUserCoupon != null && order.discountPay != null && order.discountPay > 0) {
            if(webUserCoupon.amount > order.discountPay) {
                new WebUserCouponHistory(webUserCoupon , "订单:" + order.orderNumber + "消费代金券" , order.discountPay * (-1)).save();
                webUserCoupon.amount = webUserCoupon.amount - order.discountPay;
                webUserCoupon.save();
            } else {
                new WebUserCouponHistory(webUserCoupon , "订单:" + order.orderNumber + "消费代金券 | 卡券金额小于订单折扣金额  卡券金额: " + webUserCoupon.amount + "订单折扣金额:" + order.discountPay , order.discountPay * (-1)).save();
                webUserCoupon.amount = 0d;
                webUserCoupon.save();
            }

        }
    }


    /**
     * 修改库存
     * @param order
     * @return
     */
    private static String changeProductNumber(Order order) {
        List<OrderItem> orderItems = OrderItem.getListByOrder(order);
        StringBuffer itemNames = new StringBuffer();
        for(OrderItem orderItem : orderItems) {
            itemNames.append("\n商品名称: " + orderItem.goods.name +  "  金额: " + orderItem.salePrice+ " 数量:" + orderItem.buyNumber+ ";");
            //更新商品库存数量
            ProductSpecMerchant psm = ProductSpecMerchant.findById(orderItem.goods.serialId);
            Logger.info("更新前库存:%s",psm.stock);
            psm.stock = psm.stock - orderItem.buyNumber;
            Logger.info("更新后库存:%s",psm.stock);
            psm.save();
        }
        return itemNames.toString();
    }

    /**
     * 添加赠品
     * @param order
     */
    private static void checkGiveSpecProduct(Order order) {
        Logger.info("Log 120003 Order : %s" , order);
        //判断是否有赠品
        if(order.merchant!=null && order.merchant.offeringFreebies != null &&  order.merchant.offeringFreebies ){
            Logger.info("Log 1200002  merchant  specMerchant : %s ", order.merchant);
            GiveActivitySpecProduct giveProduct = GiveActivitySpecProduct.getRandomProduct(order.amount,order.merchant.id);
            if(giveProduct != null && giveProduct.productSpecMerchant != null){
                ProductSpecMerchant specMerchant = giveProduct.productSpecMerchant ;
                Logger.info("Log 1200001  checkGiveSpecProduct  specMerchant : %s ", specMerchant.productSpec.product.name);
                // 加入 Order
                OrderItem orderItem = new  OrderItem(order,specMerchant, 0d , giveProduct.giveNum, OrderItemType.GIVE);
                orderItem.save();
                //加入 AdminOrder
                AdminOrder adminOrder = AdminOrder.findByOrder(order);
                new AdminOrderItem(orderItem , adminOrder).save();
                specMerchant.stock = specMerchant.stock - 1;
                specMerchant.save();
            }
        }
    }


}
